package com.example.myblog.controller;

import com.example.myblog.entity.User;
import com.example.myblog.mapper.UserMapper;
import com.example.myblog.util.QRCodeUtil;
import com.yc.common.vo.Result;
import org.springframework.http.MediaType;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

@RestController
public class QrcodeAction {

    //要嵌入二维码的图片路径
    private String logoPath = "d:/a.jpg";

    private static Map<String, QrStatus> uuidMap = new ConcurrentHashMap<>();

    @RequestMapping(path = "qrcode", produces = MediaType.IMAGE_JPEG_VALUE)
    public void qrcode(String content, OutputStream output) throws Exception {
        //生成二维码
        QRCodeUtil.encode(content, logoPath, output, true);
    }
    @RequestMapping(path = "sendQrcode", produces = MediaType.IMAGE_JPEG_VALUE)
    public void sendQrcode(OutputStream output, HttpServletResponse response) throws Exception {
        String uuid = UUID.randomUUID().toString();
        uuid = uuid.replaceAll("-", "");
        String url = "http://192.168.15.225/scanQr?uuid=" + uuid;
        // 设置初始状态
        uuidMap.put(uuid, new QrStatus());
        // 将uuid 写入cookie
        Cookie cookie = new Cookie("loginUUID", uuid);
        response.addCookie(cookie);
        qrcode(url, output);
    }

    @RequestMapping("scanQr")
    public ModelAndView scanQr(String uuid, ModelAndView mav) {
        QrStatus qs = uuidMap.get(uuid);
        if(qs == null){
            mav.addObject ("msg", "该二维码已过期!");
            return mav;
        }
        if (qs.status == null) {
            mav.addObject ("msg", "二维码已过期!");
        } else if (qs.status > 0) {
            mav.addObject ("msg", "该二维码已经扫过了!");
        } else {
            qs.status = 1;
            //uuidMap.put(uuid, qs);
            mav.addObject ("msg", "扫码成功!");
        }
        return mav;
    }

    /**
     * 客户端轮询
     *
     * @return
     */
    @RequestMapping("lookUuid")
    public Result lookUuid(@CookieValue String loginUUID) {
        QrStatus qs = uuidMap.get(loginUUID);
        if(qs != null && qs.status!=null){
            return new Result(qs.status, qs.status == 1 ? "已扫" : "未扫", null);
        } else {
            return Result.failure("二维码过期!");
        }
    }

    @Resource
    UserMapper userMapper;
    @RequestMapping("loginByUUID")
    public Result loginByUUID(@CookieValue String loginUUID,
                              @CookieValue Integer uid){
        QrStatus qs = uuidMap.get(loginUUID);
        if(qs == null || qs.status==0){
            return Result.failure("请先扫描二维码");
        }
        System.out.println("uid = " + uid);
        // 执行登录
        final User user = userMapper.selectById(uid);
        // 移除二维码
        uuidMap.remove(loginUUID);
        return Result.success("登录成功!", user);
    }

    private class QrStatus{
        Integer status = 0;
        // 对象创建时间
        long timestamp;

        @Override
        public String toString() {
            return "QrStatus{" +
                    "status=" + status +
                    ", timestamp=" + timestamp +
                    '}';
        }

        public QrStatus() {
            timestamp = System.currentTimeMillis();
        }
    }

    // 设置固定时间间隔执行该方法
    @Scheduled(fixedDelay = 20000)
    public void clearQr(){
        final Iterator<Map.Entry<String, QrStatus>> iterator =
                uuidMap.entrySet().iterator();
        while(iterator.hasNext()){
            final Map.Entry<String, QrStatus> next = iterator.next();
            // 判断是否超时
            if(System.currentTimeMillis() - next.getValue().timestamp > 60000){
                // 移除当前元素
                System.out.printf("删除UUID: %s : %s\n" , next.getKey(), next.getValue().toString());
                iterator.remove();
            }
        }

    }

}


